/**
 * @file app_files.cpp
 * @author Forairaaaaa
 * @brief
 * @version 0.1
 * @date 2023-11-04
 *
 * @copyright Copyright (c) 2023
 *
 */
#include "app_files.h"
#include "spdlog/spdlog.h"
#include "../../hal/hal.h"
#include "../assets/theme/theme.h"
#include "../utils/system/ui/ui.h"

#ifdef ESP_PLATFORM
#include <Arduino.h>
#include <FS.h>
#include <SD.h>
#endif

using namespace MOONCAKE::APPS;
using namespace SYSTEM::UI;

// Like setup()...
void AppFiles::onResume() { spdlog::info("{} onResume", getAppName()); }

// #ifdef ESP_PLATFORM
static const String _file_path = "/";

void __delete_all_file(File dir)
{
    while (1)
    {
        File entry = dir.openNextFile();
        if (!entry)
            break;

        if (entry.isDirectory())
        {
            // __delete_all_file(entry);
            // SD.rmdir(entry.name());
        }
        else
        {
            String path = "/" + String(entry.name());
            SD.remove(path.c_str());
            spdlog::info("SD.remove: {} ", path.c_str());
        }
        entry.flush();
        entry.close();
    }
}

// Like loop()...
void AppFiles::onRunning()
{

    if (!HAL::CheckSdCard())
        HAL::PopFatalError("没SD卡啊朋友");
    spdlog::info("try loading from SD card in {}", _file_path.c_str());

    // List dir
    auto looking_directory = SD.open(_file_path);
    std::vector<std::string> file_list = {"[File Explorer]"};
    while (1)
    {
        File entry = looking_directory.openNextFile();

        if (!entry)
            break;

        String file_string;
        if (entry.isDirectory())
        {
            file_string = String(entry.name());
        }
        else
        {
            file_string = String(entry.name()) + " " + String(entry.size() / 1024 / 1024) + "MB";
        }
        file_list.push_back(file_string.c_str());
        spdlog::info("get file: {} size: {}", entry.name(), entry.size());

        entry.close();
    }

    if (file_list.size() == 1)
        HAL::PopFatalError("no file exit");

    file_list.push_back("> Format SD Card");
    file_list.push_back("> Check SD Size");
    file_list.push_back("> Quit");

    // Create select menu
    SelectMenu menu;
    while (1)
    {
        // 等待指令
        auto selected_item = menu.waitResult(file_list);
        // 选择到了最后一项则退出
        if (selected_item == file_list.size() - 1 || selected_item == -2)
        {
            break;
        }
        else if (selected_item == file_list.size() - 2)
        {
            HAL::GetCanvas()->clear();
            HAL::GetCanvas()->fillSmoothRoundRect((240 - 220) / 2, (240 - 120) / 2, 220, 120, 20, THEME_COLOR_LIGHT);
            HAL::GetCanvas()->setTextColor(THEME_COLOR_DARK, THEME_COLOR_LIGHT);
            String line1 = "Wait a moment..";
            HAL::GetCanvas()->drawCenterString(line1, 120, 110);
            HAL::CanvasUpdate();

            String str = "Use: " + String(SD.usedBytes() / 1024 / 1024) + "/" + String(SD.totalBytes() / 1024 / 1024) + "MB";

            HAL::GetCanvas()->clear();
            HAL::GetCanvas()->fillSmoothRoundRect((240 - 220) / 2, (240 - 120) / 2, 220, 120, 20, THEME_COLOR_LIGHT);
            HAL::GetCanvas()->setTextColor(THEME_COLOR_DARK, THEME_COLOR_LIGHT);
            HAL::GetCanvas()->drawCenterString(str, 120, 110);
            HAL::CanvasUpdate();

            while (HAL::GetButton(GAMEPAD::BTN_A) != 1)
            {
                HAL::Delay(10);
            }
            HAL::Delay(500);

            continue;
        }
        else if (selected_item == file_list.size() - 3)
        {
            HAL::GetCanvas()->clear();
            HAL::GetCanvas()->fillSmoothRoundRect((240 - 220) / 2, (240 - 120) / 2, 220, 120, 20, THEME_COLOR_LIGHT);
            HAL::GetCanvas()->setTextColor(THEME_COLOR_DARK, THEME_COLOR_LIGHT);
            String line1 = "Are you Sure?";
            String line2 = "B Exit | A Sure ";
            HAL::GetCanvas()->drawCenterString(line1, 120, 110);
            HAL::GetCanvas()->drawCenterString(line2, 120, 140);
            HAL::CanvasUpdate();

            while (1)
            {
                if (HAL::GetButton(GAMEPAD::BTN_A))
                {
                    HAL::GetCanvas()->clear();
                    HAL::GetCanvas()->fillSmoothRoundRect((240 - 220) / 2, (240 - 120) / 2, 220, 120, 20, THEME_COLOR_LIGHT);
                    HAL::GetCanvas()->setTextColor(THEME_COLOR_DARK, THEME_COLOR_LIGHT);
                    String line1 = "Formating...";
                    HAL::GetCanvas()->drawCenterString(line1, 120, 110);
                    HAL::CanvasUpdate();

                    __delete_all_file(SD.open("/"));
                    break;
                }
                else if (HAL::GetButton(GAMEPAD::BTN_B))
                {
                    break;
                }
                HAL::Delay(10);
            }
            HAL::Delay(500);

            break;
        }
        else
        {
            // 选择不是最后一项，拼接出文件名称
            String selected_file_path = _file_path;
            // selected_file_path += "/";
            selected_file_path += file_list[selected_item].c_str();

            File file = SD.open(selected_file_path, FILE_READ);
            unsigned long file_size = file.size();
            file.close();

            HAL::GetCanvas()->fillSmoothRoundRect((240 - 180) / 2, (240 - 120) / 2, 180, 120, 20, THEME_COLOR_LIGHT);
            HAL::GetCanvas()->setTextColor(THEME_COLOR_DARK, THEME_COLOR_LIGHT);
            String line1 = "-File Name-";
            String line2 = selected_file_path;
            String line3 = "-File Size-";
            String line4 = String(file_size / 1024 / 1024) + "MB";
            HAL::GetCanvas()->drawCenterString(line1, 120, 80);
            HAL::GetCanvas()->drawCenterString(line2, 120, 100);
            HAL::GetCanvas()->drawCenterString(line3, 120, 120);
            HAL::GetCanvas()->drawCenterString(line4, 120, 140);
            HAL::CanvasUpdate();

            while (HAL::GetButton(GAMEPAD::BTN_A) != 1)
            {
                HAL::Delay(10);
            }
            HAL::Delay(500);
        }
    }

    destroyApp();
}

void AppFiles::onDestroy() { spdlog::info("{} onDestroy", getAppName()); }
